﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using DevExpress.Skins;
using DevExpress.LookAndFeel;
using DevExpress.UserSkins;
using DevExpress.XtraBars;
using DevExpress.XtraBars.Ribbon;
using DevExpress.XtraBars.Helpers;
using System.Reflection;
using DevExpress.XtraNavBar;
using DevExpress.XtraBars.Docking2010;
using DevExpress.XtraBars.Docking2010.Views.Tabbed;
using DevExpress.XtraEditors;
using DevExpress.XtraTabbedMdi;
using System.Configuration;
using DevExpress.XtraBars.Docking;
using DevExpress.XtraLayout;
using System.IO;
using td.Core.Xml;
using System.Threading;
using CG.Security.Principal;


namespace td.Core
{
    public partial class DefaultWorkBench : RibbonForm
    {
      

        /// <summary>
        /// 保存所有的由插件生成的按钮
        /// </summary>
        public List<td.Core.ToolButton> ToolButtons = new List<td.Core.ToolButton>();
        public List<td.Core.NavBarButton> NavBarButtons = new List<NavBarButton>();
        public List<AbstractPad> dockPanels = new List<AbstractPad>();
        public List<td.Core.AbstractViewContent> ViewContents = new List<AbstractViewContent>();
        public List<PopupMenu> Contextmenus = new List<PopupMenu>();
        
        XtraTabbedMdiManager dm = new XtraTabbedMdiManager();
        /// <summary>
        /// TAB关闭时触发，sender为关闭的TABPAGE
        /// </summary>
        public event EventHandler TabPageClosing;
        /// <summary>
        /// TAB添加时触发，sender为TABPAGE
        /// </summary>
        public event EventHandler TabPageAdded;
        public event EventHandler TitleChanged;
        public event EventHandler TabPageClosed;
        public event EventHandler WorkBenchCreated;
        public event EventHandler ActivateTabPageChanged;



        string iconFileName = "";

        private string title="";
        public string Title
        {
            get { return this.title; }
            set
            {
                if (this.TitleChanged != null) this.TitleChanged(this.Title, EventArgs.Empty);
                this.title = value;
                this.Text = title + " -当前登录用户：" + Thread.CurrentPrincipal.Identity.Name;
            }
        }
        /// <summary>
        /// 保存所有由插件生成的TAB页面
        /// </summary>
        
        public DefaultWorkBench()
        {
            InitializeComponent();
            InitSkinGallery();
            Application.Idle += new EventHandler(Application_Idle);
            this.CenterToScreen();

            this.MdiChildActivate += new EventHandler(DefaultWorkBench_MdiChildActivate);

        }

        void DefaultWorkBench_MdiChildActivate(object sender, EventArgs e)
        {
            if (this.ActivateTabPageChanged != null)
            {
                this.ActivateTabPageChanged(sender, e);
            }
        }
       
        /// <summary>
        /// 在退出时提示
        /// </summary>
        /// <param name="msg"></param>
        protected override void WndProc(ref Message msg)
        {
            if ((msg.Msg == 0x112) && (msg.WParam.ToInt32() == 0xf060))
            {
                if (XtraMessageBox.Show("确定要退出系统吗？", "关闭系统", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.Cancel)
                {
                    return;
                }
                else
                {
                    SaveSettings();
  
                }
            }
            base.WndProc(ref msg);
            
        }
        
        /// <summary>
        /// 更新按钮的状态
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void Application_Idle(object sender, EventArgs e)
        {
            UpdateToolButtonStautes();
            WorkBenchSingleTon.WorkBench.Title = WorkBenchSingleTon.WorkBench.Title;
        }

        /// <summary>
        /// 注册换肤
        /// </summary>
        void InitSkinGallery()
        {
            SkinHelper.InitSkinGallery(rgbiSkins, true);
        }
        /// <summary>
        /// 根据btn生产相应的按钮
        /// </summary>
        /// <param name="btn"></param>
        void AddToolButton(td.Core.AbstractToolButtonCommand btn)
        {
            ToolButton button = new ToolButton(btn,this);
            this.ToolButtons.Add(button);
            var page = this.ribbonControl.Pages.GetPageByText(btn.PageName);
            if (page == null)
            {
                int pos = this.ribbonControl.Pages.Count - 1;
                page = new RibbonPage(btn.PageName);
                this.ribbonControl.Pages.Insert(pos,page);
            }
            var group = page.Groups.GetGroupByText(btn.GroupName);
            if (group == null)
            {
                group = new RibbonPageGroup(btn.GroupName);
                this.ribbonControl.Pages[btn.PageName].Groups.Add(group);
            }
         
            group.ItemLinks.Add(button);
            
            UpdateToolButtonStautes();
        }
        /// <summary>
        /// 将NavBarButton添加到左侧的导航条中。
        /// </summary>
        /// <param name="btn"></param>
        void AddGroupButton(td.Core.AbstractToolButtonCommand btn)
        {
            NavBarButton nbb = new NavBarButton(btn, this);
            this.NavBarButtons.Add(nbb);
            NavBarGroup group = this.navBarControl.Groups[btn.PageName];
            if (group == null)
            {
                group = new NavBarGroup(btn.PageName);
                group.Name = btn.PageName;
                //group.LargeImage = btn.largeImage;
                this.navBarControl.Groups.Add(group);
            }
            group.ItemLinks.Add(nbb);
            UpdateToolButtonStautes();
        }
        /// <summary>
        /// 更新按钮的状态
        /// </summary>
        public void UpdateToolButtonStautes()
        {
            foreach (var t in this.ToolButtons)
            {
                t.UpdateStatus();
            }
            foreach (var t in this.NavBarButtons)
            {
                t.UpdateStatus();
            }

        }
        #region Pad相关函数
        public DockPanel GetPanelFromDockMangerByText(string caption)
        {
            for (int i = 0; i < this.myDockManager1.Panels.Count; i++)
            {
                if (this.myDockManager1.Panels[i].Text == caption)
                {
                    return this.myDockManager1.Panels[i];
                }
            }
            return null;
        }
        public DockPanel GetPanelFromDockMangerByName(string caption)
        {
            for (int i = 0; i < this.myDockManager1.Panels.Count; i++)
            {
                if (this.myDockManager1.Panels[i].Name == caption)
                {
                    return this.myDockManager1.Panels[i];
                }
            }
            return null;
        }
        public DockPanel GetPanelFromDockManager(string caption)
        {
            try
            {
                var dp = GetPanelFromDockMangerByName(caption);
                if (dp == null) return null;
                else return dp;
            }
            catch (Exception ee)
            {
                return null;
            }
        }
        public void AddPad(AbstractPad pad)
        {
            var  panel1 = (MyDockPanel)myDockManager1.AddPanel(DockingStyle.Right);
            panel1.Text = pad.Title;
            panel1.Name = pad.Title;
            panel1.ID = pad.guid;
            panel1.ShowAutoHideButton = pad.ShowAutoHideButton;
            panel1.ShowCloseButton = pad.ShowCloseButton;
            panel1.Icon = pad.Icon;
            panel1.ViewContentControl = pad.ViewContentControl;
   
        }
        string DockingLayoutFile =Application.StartupPath+ "\\DockingLayoutFile.xml";
        private void RestoreSettings()
        {
            if (System.IO.File.Exists(DockingLayoutFile))
                myDockManager1.RestoreLayoutFromXml(DockingLayoutFile);
        }
        private void SaveSettings()
        {
            myDockManager1.SaveLayoutToXml(DockingLayoutFile);
        }

        public void ShowPad(string caption)
        {
            var pad = this.GetPanelFromDockMangerByName(caption);
            if(pad!=null)
            {
                pad.Show();
            }
        }
        public void HidePad(string caption)
        {
            var pad = this.GetPanelFromDockMangerByName(caption);
            if (pad != null)
            {
                pad.Hide();
            }
        }
        public DockPanel GetPad(string caption)
        {
            return this.GetPanelFromDockMangerByName(caption);
        }
        #endregion
        #region Tab页面相关函数
        /// <summary>
        /// 添加一个TAB页面
        /// </summary>
        /// <param name="view"></param>
        public  void AddView(AbstractViewContent view)
        {
            if (this.MdiChildren.Length >= 40)
            {
                MessageBox.Show("窗口数量超过最大限制，请关闭部分不用窗口后继续！","错误",MessageBoxButtons.OK,MessageBoxIcon.Error);
                return;
            }
            ViewContent v = new ViewContent(view, this);
            v.FormClosing += new FormClosingEventHandler(v_FormClosing);
            v.FormClosed += new FormClosedEventHandler(v_FormClosed);
            v.MdiParent = this;
            v.Show();
            if (this.TabPageAdded != null)
            {
                this.TabPageAdded(v, EventArgs.Empty);
            }
            
        }

        void v_FormClosed(object sender, FormClosedEventArgs e)
        {
            if (this.TabPageClosed != null)
            {
                this.TabPageClosed(sender, EventArgs.Empty);
            }
        }
        /// <summary>
        /// FormClosing(object sender, FormClosingEventArgs e)
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void v_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (this.TabPageClosing != null)
            {
                this.TabPageClosing(sender, e);
            }
        }
        /// <summary>
        /// 关闭当前TAB页面
        /// </summary>
        public void CloseActiveTabPage()
        {
          //  var t = this.dm.View.ActiveDocument;
            //if (t != null) t.Dispose();
            var t = this.MdiChildren;
            if (t.Length > 0)
            {
                this.ActiveMdiChild.Close();
            }
        }
        public IViewContent GetTabPage(string caption)
        {
            foreach (var c in this.MdiChildren)
            {
                if (c.Text == caption)
                {
                    return (IViewContent)c;
                }
            }
            return null;
        }
        /// <summary>
        /// 将指定标题的TAB显示到前端
        /// </summary>
        /// <param name="caption"></param>
        public void ActiveTabPage(string caption)
        {
            foreach (var c in this.MdiChildren)
            {
                if (c.Text == caption)
                {
                    c.BringToFront();
                    return;
                }
            }
        }
        
        /// <summary>
        /// 获取当前TAB页面 ,如果没有返回null
        /// </summary>
        /// <returns></returns>
        public IViewContent GetActivteTabPage()
        {
            if(this.MdiChildren.Length>0)
                if (this.ActiveMdiChild != null)
                    return (IViewContent)this.ActiveMdiChild;
            return null;
        }
        #endregion
        #region 加载插件相关  直接从DLL中加载，现已改为从XML中加载，故这部分没有使用了。
        /// <summary>
        /// 从指定的DLL中反射出插件类，并加载
        /// </summary>
        void LoadAddin()
        {
            var files = System.IO.Directory.GetFiles(Application.StartupPath, "*.addin.dll");
            foreach (var file in files)
            {
                LoadAddinFromOneDll(file);
            }
        }
        /// <summary>
        /// 从DLL文件中加载插件，文件名要求为*.addin.dll，继承于 AbstractToolButtonCommand（Ribbion上的按钮）或AbstractViewContent（TAB页面）
        /// </summary>
        /// <param name="path"></param>
        private void LoadAddinFromOneDll(string path)
        {            
            Assembly assembly = Assembly.LoadFrom(path);
            Type[] types = assembly.GetTypes();
            foreach (var t in types)
            {
                var obj = assembly.CreateInstance(t.ToString());
                if (obj is td.Core.AbstractToolButtonCommand)
                {
                    AddToolButton((td.Core.AbstractToolButtonCommand)obj);
                    AddGroupButton((td.Core.AbstractToolButtonCommand)obj);
                }
                else if (obj is td.Core.AbstractViewContent)
                {
                    AddView((td.Core.AbstractViewContent)obj);
                }
                else if (obj is td.Core.AbstractPad)
                {
                    AddPad((td.Core.AbstractPad)obj);
                }
            }
        }
        /// <summary>
        /// 加载插件
        /// </summary>
        private void LoadAddinAndLayOut()
        {
            dm.MdiParent = this;
            //LoadAddin();
            //RestoreSettings();
        }
        #endregion

        private void DefaultWorkBench_Load(object sender, EventArgs e)
        {
            this.siStatus.Caption = "就绪";
            this.siInfo.Caption = "";
        }

        /// <summary>
        /// 设置状态栏的状态信息，不能在其他线程中设置
        /// </summary>
        /// <param name="info">显示的信息</param>
        public void SetStatusInfo(string info)
        {
            this.siStatus.Caption = info;
        }
        /// <summary>
        /// 设置状态栏消息，不能在其他线程中执行
        /// </summary>
        /// <param name="msg">显示的消息</param>
        public void SetStatusMsg(string msg)
        {
            this.siInfo.Caption = msg;
        }
        #region 从XML加载插件相关函数

        public AddIn addin { get; set; }

        public void InitializeWorkbench()
        {
            dm.MdiParent = this;
            try
            {                
                LoadPadAddinFromXml();
                LoadToolButtonsAddinFromXml();
                this.navBarControl.Groups[0].Expanded = true;

                this.addin = AddIn.GetInstance();
                for (int j = 0; j < this.addin.AutoRun.Count; j++)
                {
                    td.Core.Xml.AutoStartXml autorunxml = this.addin.AutoRun[j];
                    AbstractToolButtonCommand btn = this.CreateAutoRun(autorunxml);
                    if (btn != null)
                    {
                        btn.Run();
                    }            
                }
                if (this.WorkBenchCreated != null)
                {
                    this.WorkBenchCreated(this, EventArgs.Empty);
                }

                this.Title = this.addin.Name.Trim();
                if (File.Exists(this.iconFileName))
                {
                    base.Icon = new Icon(this.iconFileName);
                }
            }
            catch (Exception ee)
            {
                MessageBox.Show(ee.ToString());
            }
         
        }
    
        private AbstractToolButtonCommand CreateAutoRun(AutoStartXml autorunxml)
        {
            AbstractToolButtonCommand btn = (AbstractToolButtonCommand)this.addin.CreateObject(autorunxml.Class);
            return btn;

        }

        private void LoadToolButtonsAddinFromXml()
        {
            try
            {
                this.addin = AddIn.GetInstance();
                for (int j = 0; j < this.addin.ToolButtons.Count; j++)
                {
                    ToolButtonXml btnxml = this.addin.ToolButtons[j];
                    AbstractToolButtonCommand btn = this.CreateToolButton(btnxml);
                    if (btn != null)
                    {
                        this.AddToolButton(btn);
                        if (btnxml.ShowInNavBar != null)
                        {
                            if (!(btnxml.ShowInNavBar == "" || btnxml.ShowInNavBar.Equals("")))
                            {
                                this.AddGroupButton(btn);
                            }
                        }
                    }
                }
            }
            catch (Exception exception)
            {
                //  LoggingService.Error("初始化布局发生错误：" + exception.Message);
            }
        }

        private AbstractToolButtonCommand CreateToolButton(ToolButtonXml btnxml)
        {
            AbstractToolButtonCommand btn = (AbstractToolButtonCommand)this.addin.CreateObject(btnxml.Class);
            if (btn != null)
            {
                if (!(btnxml.Caption == null || btnxml.Caption.Equals("")))
                {
                    btn.Caption = btnxml.Caption;
                }
                if (!(btnxml.GroupName == null || btnxml.GroupName.Equals("")))
                {
                    btn.GroupName = btnxml.GroupName;
                }
                if (!(btnxml.PageName == null || btnxml.PageName.Equals("")))
                {
                    btn.PageName = btnxml.PageName;
                }
                if (!(btnxml.ToolTip == null || btnxml.ToolTip.Equals("")))
                {
                    btn.ToolTip = btnxml.ToolTip;
                }
                if (!(btnxml.ShortCut == null || btnxml.ShortCut.Equals("")))
                {
                    btn.ShortCut = btnxml.ShortCut;
                }
                if (!(btnxml.largeImage == null || btnxml.largeImage.Equals("")))
                {
                    try
                    {
                        Image image = Image.FromFile(Application.StartupPath + "\\images\\" + btnxml.largeImage);
                        btn.largeImage = image;
                    }
                    catch (Exception ee)
                    {
                        MessageBox.Show(ee.ToString());
                        btn.largeImage = null;
                    }
                }
                if (!(btnxml.smallImage == null || btnxml.smallImage.Equals("")))
                {
                    try
                    {
                        Image image = Image.FromFile(Application.StartupPath + "\\images\\" + btnxml.smallImage);
                        btn.smallImage = image;
                    }
                    catch (Exception ee)
                    {
                        MessageBox.Show(ee.ToString());
                        btn.smallImage = null;
                    }
                }
            }
            return btn;
        }

        private void LoadPadAddinFromXml()
        {
            try
            {
                this.addin = AddIn.GetInstance();
                for (int j = 0; j < this.addin.Pads.Count; j++)
                {
                    PadXml padxml = this.addin.Pads[j];
                    IPad pad = this.CreatePad(padxml);
                    if (pad != null)
                    {
                        this.ShowPad((AbstractPad)pad);
                    }
                }
                RestoreSettings(); //从布局文件中加载布局
            }
            catch (Exception exception)
            {
                //  LoggingService.Error("初始化布局发生错误：" + exception.Message);
            }
        }


        private AbstractPad CreatePad(PadXml padxml)
        {
            var  content = (AbstractPad)this.addin.CreateObject(padxml.Class);
            if (content != null)
            {
                if (!((padxml.Title == null) || padxml.Title.Equals("")))
                {
                    content.Title = padxml.Title;
                }
                if(! (padxml.ShowCloseButton == null || padxml.ShowCloseButton.Equals("")))
                {
                    content.ShowCloseButton = Convert.ToBoolean(padxml.ShowCloseButton);
                }
                if (!(padxml.guid == null || padxml.guid.Equals("")))
                {
                    content.guid = Guid.Parse(padxml.guid);
                }
                if (!(padxml.ShowAutoHideButton == null || padxml.ShowAutoHideButton.Equals("")))
                {
                    content.ShowAutoHideButton = Convert.ToBoolean(padxml.ShowAutoHideButton);
                }

                if ((padxml.Icon == null) || padxml.Icon.Equals(""))
                {
                    return content;
                }
                try
                {
                    Image icon = (Image.FromFile(Application.StartupPath+"\\"+padxml.Icon));
                    if (icon != null)
                    {
                        content.Icon = icon;
                    }
                }
                catch
                {
                   // LoggingService.Error("无法找到面板[" + padxml.Title + "]图标:" + padxml.Icon);
                }
            }
            return content;
        }

        public void ShowPad(AbstractPad pad)
        {
            if (pad != null)
            {
                if (this.dockPanels.Contains(pad))
                {
                    var c = this.dockManager1.Panels[(pad).guid];
                    if (c != null)
                    {
                        c.Text = pad.Title;
                        
                        c.Show();
                        c.BringToFront();
                    }
                }
                else
                {                   
                    this.dockPanels.Add(pad);
                    AddPad(pad);
                }
            }
        }

        #endregion

        public Keys ParseShortcut(string shortcutString)
        {
            Keys none = Keys.None;
            shortcutString = shortcutString.Replace(" ", "");
            if (shortcutString.Length > 0)
            {
                try
                {
                    foreach (string str in shortcutString.Split(new char[] { '+' }))
                    {
                        none |= (Keys)Enum.Parse(typeof(Keys), str);
                    }
                }
                catch (Exception exception)
                {
                   // LoggingService.Error("菜单[" + this.item.Label + "]的快捷键设置失败：" + exception.Message);
                    return Keys.None;
                }
            }
            return none;
        }
        /// <summary>
        /// New 按钮实现新建 ，根据当前页面是否为IToolButton接口执行OnNew函数
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void iNew_ItemClick(object sender, ItemClickEventArgs e)
        {
            var view = this.GetActivteTabPage();
            if ( view != null)
            {
                if (view.ViewContentControl is IToolButton)
                {
                    ((IToolButton)(view.ViewContentControl)).OnNew();
                }
            }
        }

    }
}